package valuer

import (
	"database/sql"
	"my_framework/orm/internal/errs"
	"my_framework/orm/model"
	"reflect"
)

type reflectValue struct {
	model *model.Model
	// 对应T的指针
	//val any
	val reflect.Value
}

func (r reflectValue) Filed(name string) (any, error) {
	//if _, ok := r.val.Type().FieldByName(name); !ok {
	//	return nil, errors.New("")
	//}
	//val:=r.val.FieldByName(name)
	//if val==(reflect.Value{}){
	//	// err
	//}
	return r.val.FieldByName(name).Interface(), nil
}

var _ Creator = NewReflectValue

func (r reflectValue) SetColumns(rows *sql.Rows) error {
	// select出来多少列
	cs, err := rows.Columns()
	if err != nil {
		return err
	}

	vals := make([]any, 0, len(cs))
	valElems := make([]reflect.Value, 0, len(cs))
	for _, c := range cs {
		// c是列名
		fd, ok := r.model.ColumnMap[c]
		if !ok {
			return errs.NewErrUnknownColumn(c)
		}
		// 反射创建实例
		// 这里创建的实例是原本类型的指针
		val := reflect.New(fd.Typ)
		vals = append(vals, val.Interface())
		valElems = append(valElems, val.Elem())
	}

	err = rows.Scan(vals...)
	if err != nil {
		return err
	}

	// 把vals填入tp
	//tpValue := reflect.ValueOf(r.val)
	tpValue := r.val
	for i, c := range cs {
		fd, ok := r.model.ColumnMap[c]
		if !ok {
			return errs.NewErrUnknownColumn(c)
		}
		tpValue.Elem().FieldByName(fd.GoName).
			//Set(reflect.ValueOf(vals[i]).Elem())
			Set(valElems[i])
	}
	return nil
}

func NewReflectValue(model *model.Model, val any) Value {
	return reflectValue{
		model: model,
		val:   reflect.ValueOf(val).Elem(),
	}
}
